<?php
namespace app\services\tools;

use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;
use Qiniu\Cdn\CdnManager;

class QiniuService
{
    protected $bucket = '';
    protected $auth;
    protected $bucketManager;

    public function __construct()
    {
        $config = config('qiniu.default');
        $this->auth = new Auth($config['access_key'], $config['secret_key']);
        $this->bucketManager = new BucketManager($this->auth);
        $this->bucket = $config['bucket'] ?? '';
    }

    /**
     * 设置bucket
     * @param $bucket
     */
    public function setBucket($bucket)
    {
        $this->bucket = $bucket;
    }

    /**
     * 获取该帐号下的bucket
     */
    public function buckets()
    {
        return $this->bucketManager->buckets();
    }

    /**
     * 获取该bucket下所绑的域名
     */
    public function domains()
    {
        return $this->bucketManager->domains($this->bucket);
    }

    /**
     * 显示文件列表
     * @param $prefix  //要列取文件的公共前缀
     * @param int $limit //本次列举的条目数
     * @param string $marker //上次列举返回的位置标记，作为本次列举的起点信息。
     * @param string $delimiter //分界符
     * @return bool|mixed|string
     */
    public function list($prefix, $limit = 100, $marker = '', $delimiter = '')
    {
        list($ret, $err) = $this->bucketManager->listFiles($this->bucket, $prefix, $marker, $limit, $delimiter);
        if (is_array($ret)) {
            $item = $ret['items'] ?? '';
            if ($item) {
                return $item;
            }
        }
        return false;
    }

    /**
     *
     * @param $url
     * @param $key
     * @return bool
     */
    public function fetch($url, $key)
    {
        list($ret, $err) = $this->bucketManager->fetch($url, $this->bucket, $key);
        if ($err !== null) {
            return false;
        }
        return $ret;
    }

    /**
     * 删除一个或者多个资源
     * @param $keys
     * @return bool
     */
    public function delete(array $keys)
    {
        $ops = $this->bucketManager->buildBatchDelete($this->bucket, $keys);
        list($ret, $err) = $this->bucketManager->batch($ops);

        if (is_array($ret)) {
            $code = $ret[0]['code'] ?? '';
            if ($code == 200) {
                return true;
            }
        }

        if ($err !== null) {
            return false;
        }

        return false;
    }

    /**
     * 获取资源的元数据
     * @param $key
     * @return bool
     */
    public function stat($key)
    {
        list($ret, $err) = $this->bucketManager->stat($this->bucket, $key);
        if ($err !== null) {
            return false;
        }
        return $ret;
    }

    /**
     * 上传本地文件到bucket 如果key 已存在，会失败
     * @param $filePath
     * @param $key
     * @return bool
     */
    public function upload($filePath, $key)
    {
        $token = $this->auth->uploadToken($this->bucket);

        $uploadMgr = new UploadManager();
        list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);

        if ($err !== null) {
            //dump($err);
            return false;
        }
        return $ret;
    }

    /**
     * 替换已存在的key
     * @param $filePath
     * @param $key
     * @return bool
     */
    public function replace($filePath, $key)
    {
        /**
         * 检查是否存在资源，有就删除
         */
        $this->stat($key) && $this->delete([$key]);

        $token = $this->auth->uploadToken($this->bucket);
        $uploadMgr = new UploadManager();

        list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
        if ($err !== null) {
            return false;
        }
        return $ret;
    }

    /**
     * 刷新资源 url方式 dir要审请
     * @param $key
     * @return bool
     */
    public function refresh($key)
    {
        list($ret, $err) = $this->bucketManager->domains($this->bucket);
        if ($ret) {
            $domain = isset($ret[0]) ? 'http://'.$ret[0] :'';
            $cdnManager = new CdnManager($this->auth);
            $urls = [
                $domain . '/' . ltrim($key, '/'),
            ];
            $dirs = [];
            list($ret, $err) = $cdnManager->refreshUrlsAndDirs($urls, $dirs);
            if ($err !== null) {
                return false;
            }
            return $ret;
        }
    }
}
